import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/*
 * @lc app=leetcode.cn id=40 lang=java
 *
 * [40] 组合总和 II
 *
 * https://leetcode-cn.com/problems/combination-sum-ii/description/
 *
 * algorithms
 * Medium (57.35%)
 * Likes:    159
 * Dislikes: 0
 * Total Accepted:    26.3K
 * Total Submissions: 45.8K
 * Testcase Example:  '[10,1,2,7,6,1,5]\n8'
 *
 * 给定一个数组 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合。
 *
 * candidates 中的每个数字在每个组合中只能使用一次。
 *
 * 说明：
 *
 *
 * 所有数字（包括目标数）都是正整数。
 * 解集不能包含重复的组合。 
 *
 *
 * 示例 1:
 *
 * 输入: candidates = [10,1,2,7,6,1,5], target = 8,
 * 所求解集为:
 * [
 * ⁠ [1, 7],
 * ⁠ [1, 2, 5],
 * ⁠ [2, 6],
 * ⁠ [1, 1, 6]
 * ]
 *
 *
 * 示例 2:
 *
 * 输入: candidates = [2,5,2,1,2], target = 5,
 * 所求解集为:
 * [
 * [1,2,2],
 * [5]
 * ]
 *
 */
// @lc code=start
class Solution {
    int[] candidates;
    Set<List<Integer>> res = new HashSet<>();
    List<Integer> list = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        this.candidates = candidates;


        dfs(target, 0);
        return new ArrayList<>(this.res);
    }

    void dfs(int target, int left) {
        if(target == 0) {
            this.res.add(new ArrayList<>(this.list));
            System.out.println("haha");
            return;
        }

        if(target < 0 || left >= candidates.length) {
            return;
        }

        for (int i=left; i < candidates.length; i++) {
            this.list.add(candidates[i]);
            dfs(target-candidates[i], i+1);
            this.list.remove(this.list.size()-1);
        }
    }
}
// @lc code=end

